﻿using System.Data.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using KPIS.GERP.Models;
using KPIS.GERP.Models.ICM;
using KPIS.GERP.Models.ICM.ViewModel;

namespace KPIS.GERP.WEB.GIMS.Class
{
    public static class OfficeSupplyLotReport
    {
        public static List<MasResourceItem> GetResourceItemOffice(DateTime StartDate, DateTime EndDate, int bgSourceId,
            out List<ReportOfficeSuppliesLot2> officeSuppliesLot2s, out List<ReportOfficeSuppliesLot2> officeSuppliesLot2PrevAlls)
        {
            officeSuppliesLot2s = Report4SuppliesLot(StartDate, EndDate, bgSourceId);
            officeSuppliesLot2PrevAlls = Report4SuppliesLotPrevAll(StartDate, bgSourceId);
            List<int> modelIds = new List<int>(); 
            foreach (var l in officeSuppliesLot2s)
            {
                if (modelIds.All(o => o != l.ResItemId) )
                {
                    modelIds.Add(l.ResItemId);
                }
            }
            foreach (var l in officeSuppliesLot2PrevAlls)
            {
                if (modelIds.All(o => o != l.ResItemId))
                {
                    modelIds.Add(l.ResItemId);
                }
            }
            return new GERPContext().MasResourceItems.Include(
                o => o.MasResourceSubGroup.MasResourceGroup.MasResourceType).Include(o => o.MasUnit)
                .Where(o => modelIds.Contains(o.ResItemId)).OrderBy(o=>o.Code)
                .ToList();
        }

        public static List<ReportOfficeSuppliesLot2> Report4SuppliesLot(DateTime StartDate, DateTime EndDate, int bgSourceId)
        {
            StartDate = StartDate.Date;
            EndDate = EndDate.Date.AddDays(1).AddSeconds(-1);

            using (GERPContext context = new GERPContext())
            {  
                // รับ
                var queryReceiveD =
                    (from a in
                        context.OfficeSuppliesLots.Include(
                            o => o.MasResourceItem.MasResourceSubGroup.MasResourceGroup.MasResourceType)
                        join f in context.ReceiveDtls on a.ReceiveDtlId equals f.ReceiveDtlId
                        join g in context.Receiveds on f.ReceiveId equals g.ReceiveId
                        where a.RecordStatus != "D" && // e.ResTypeId == 1 && 
                              a.CreatedWhen >= StartDate &&
                              a.CreatedWhen <= EndDate
                        select new
                        {
                            a,
                            b = a.MasResourceItem,
                            c = a.MasResourceItem.MasResourceSubGroup,
                            d = a.MasResourceItem.MasResourceSubGroup.MasResourceGroup,
                            e = a.MasResourceItem.MasResourceSubGroup.MasResourceGroup.MasResourceType,
                            f,
                            g
                        }).ToList();

                if (bgSourceId != 0)
                {
                    queryReceiveD = queryReceiveD.Where(o => o.a.BgSourceId == bgSourceId).ToList();
                }

                var queryReceive = queryReceiveD.Select(o => new
                {
                    o.g.ReceiveDate,
                    ReceiveCode =
                        !string.IsNullOrEmpty(o.g.ReceiveCode) ? o.g.ReceiveCode : "RECEIVEID" + o.g.ReceiveId,
                    o.f.Price,
                    o.f.Quantity,
                    o.b.ResItemId,
                    o.a.BgSourceId,
                    ResItemCode = o.b.Code,
                    o.a.OfficeSuppliesLotId,
                    o.f.ReceiveDtlId,
                    o.g.ReceiveId
                });
                var models = queryReceiveD.ToList(); 


                List<ReportOfficeSuppliesLot2> Dics = new List<ReportOfficeSuppliesLot2>();

                foreach (var receive in queryReceive)
                {
                    ReportOfficeSuppliesLot2 dic = new ReportOfficeSuppliesLot2();

                    dic.Amount = receive.Price * receive.Quantity;
                    dic.Qty = receive.Quantity;
                    dic.Price = receive.Price;
                    dic.ResItemCode = receive.ResItemCode;
                    dic.Code = receive.ReceiveCode;
                    dic.Date = receive.ReceiveDate;
                    dic.ResItemId = receive.ResItemId;
                    dic.Type = "R";
                    Dics.Add(dic);
                }

                // จ่าย
                var queryDispense = (from a in context.DispenseHistorys
                                     join b in context.Dispenses.Include("RequestParcel") on a.DispenseId equals b.DispenseId
                                     join c in context.MasResourceItems on a.ResItemId equals c.ResItemId
                                     where b.DispenseDate >= StartDate && b.DispenseDate <= EndDate
                                     select new { a.Price, a.Quantity, a.RefNo, b.DispenseDate, c.ResItemId, b.RequestParcel.IcmReqCode, ResItemCode = c.Code });

                foreach (var dispense in queryDispense)
                {
                    ReportOfficeSuppliesLot2 dic = new ReportOfficeSuppliesLot2();

                    dic.Price = Convert.ToDecimal(dispense.Price);
                    dic.Qty = Convert.ToDecimal(dispense.Quantity);
                    dic.ResItemCode = dispense.ResItemCode;
                    dic.Code = dispense.IcmReqCode + (string.IsNullOrWhiteSpace(dispense.RefNo) ? "" : "-" + dispense.RefNo);
                    dic.Amount = Convert.ToDecimal(dispense.Price * dispense.Quantity);
                    dic.Date = Convert.ToDateTime(dispense.DispenseDate);
                    dic.ResItemId = dispense.ResItemId;
                    dic.Type = "D";
                    Dics.Add(dic);
                }

                return Dics.OrderBy(m => m.ResItemCode).ToList();
            }
        }

        public static List<ReportOfficeSuppliesLot2> Report4SuppliesLotPrevAll(DateTime StartDate, int bgSourceId)
        {
            StartDate = StartDate.Date;
            using (GERPContext context = new GERPContext())
            {
                // รับ
                var x = (from a in context.OfficeSuppliesLots
                         join b in context.MasResourceItems on a.ResItemId equals b.ResItemId
                         join c in context.MasResourceSubGroups on b.ResSubGrpId equals c.ResSubGrpId
                         join d in context.MasResourceGroups on c.ResGrpId equals d.ResGrpId
                         join e in context.MasResourceTypes on d.ResTypeId equals e.ResTypeId
                         join f in context.ReceiveDtls on a.ReceiveDtlId equals f.ReceiveDtlId
                         join g in context.Receiveds on f.ReceiveId equals g.ReceiveId
                         where a.RecordStatus != "D" &&
                         a.CreatedWhen < StartDate &&
                         (bgSourceId == 0 ||
                            (bgSourceId == -1 && a.BgSourceId == null ||
                            bgSourceId != -1 && a.BgSourceId == bgSourceId)
                         )
                         select new
                         {
                             f.ResourceItemId,
                             f.Quantity,
                             f.Price
                         }).ToList();
                
                List<ReportOfficeSuppliesLot2> models = new List<ReportOfficeSuppliesLot2>();
                foreach (var x1 in x)
                {
                    decimal dQtyReceive = x.Sum(m => m.Quantity);
                    decimal dSumReceive = x.Sum(m => m.Price*m.Quantity);

                    // จ่าย
                    var y = (from a in context.DispenseHistorys
                        join b in context.Dispenses on a.DispenseId equals b.DispenseId
                        where a.ResItemId == x1.ResourceItemId &&
                            b.DispenseDate < StartDate
                        select new
                        {
                            a.Price,
                            a.Quantity
                        }).ToList();


                    decimal dQtyDispense = y.Sum(m => m.Quantity ?? 0);
                    decimal dSumDispense = y.Sum(m => (m.Price ?? 0)*(m.Quantity ?? 0));

                    // ยกมา
                    var model = new ReportOfficeSuppliesLot2();

                    model.ResItemId = x1.ResourceItemId.Value;
                    model.Qty = dQtyReceive - dSumDispense;
                    model.Amount = dSumReceive - dSumDispense;
                    model.Price = model.Qty != 0 ? model.Amount/model.Qty : 0;
                    model.Type = "T";
                    models.Add(model);
                }
                return models;
            }
        }

        public static ReportOfficeSuppliesLot2 Report4SuppliesLotPrev(DateTime StartDate, int ResItemId, int bgSourceId)
        {
            StartDate = StartDate.Date;
            using (GERPContext context = new GERPContext())
            {
                // รับ
                var x = (from a in context.OfficeSuppliesLots
                         join b in context.MasResourceItems on a.ResItemId equals b.ResItemId
                         join c in context.MasResourceSubGroups on b.ResSubGrpId equals c.ResSubGrpId
                         join d in context.MasResourceGroups on c.ResGrpId equals d.ResGrpId
                         join e in context.MasResourceTypes on d.ResTypeId equals e.ResTypeId
                         join f in context.ReceiveDtls on a.ReceiveDtlId equals f.ReceiveDtlId
                         join g in context.Receiveds on f.ReceiveId equals g.ReceiveId 
                         where a.RecordStatus != "D" &&
                         a.ResItemId == ResItemId && 
                         a.CreatedWhen < StartDate &&
                         (bgSourceId == 0 ||
                            (bgSourceId == -1 && a.BgSourceId == null ||
                            bgSourceId != -1 && a.BgSourceId == bgSourceId)
                         )
                         select new
                         {
                             f.Quantity,
                             f.Price
                         }).ToList();
                decimal dQtyReceive = x.Sum(m => m.Quantity);
                decimal dSumReceive = x.Sum(m => m.Price * m.Quantity);

                // จ่าย
                var y = (from a in context.DispenseHistorys
                         join b in context.Dispenses on a.DispenseId equals b.DispenseId 
                         where a.ResItemId == ResItemId &&
                         b.DispenseDate < StartDate
                         select new
                         {
                             a.Price,
                             a.Quantity
                         }).ToList();
                decimal dQtyDispense = y.Sum(m => m.Quantity ?? 0);
                decimal dSumDispense = y.Sum(m => (m.Price ?? 0) * (m.Quantity ?? 0));

                // ยกมา
                var model = new ReportOfficeSuppliesLot2();

                model.ResItemId = ResItemId;
                model.Qty = dQtyReceive - dSumDispense;
                model.Amount = dSumReceive - dSumDispense;
                model.Price = model.Qty != 0 ? model.Amount / model.Qty : 0;
                model.Type = "T";

                return model;
            }
        }
    }
}